import {
  Box,
  Center,
  Flex,
  Text,
  useColorModeValue,
  useToast,
  VStack,
} from '@chakra-ui/react';

import {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useLayoutEffect,
  useState,
} from 'react';
import { useDropzone } from 'react-dropzone';
import { useTranslation } from 'react-i18next';

import { createPreviewMedia } from '@/common/utils/upload';

const MAX_FILES = 200;

export type FilePreview = (File | Blob) & { preview: string; uniqId: string };
interface ImagesUploaderProps {
  uploadedFiles: FilePreview[];
  handleFileAccept: (files: FilePreview[]) => void;
}
export default forwardRef(function ImagesUploader(
  { handleFileAccept, uploadedFiles }: ImagesUploaderProps,
  ref
) {
  const [errorMessages, setErrorMessages] = useState<string[]>([]);

  const toast = useToast();
  const { t } = useTranslation();
  const textShadow = useColorModeValue('0 0 20px black', '0 0 20px white');
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    accept: {
      // 'image/png': ['.png'],
      // 'image/jpeg': ['.jpeg', '.jpg'],
      'image/jpeg': ['.jpg'],
    },
    maxSize: 100000000, // 100mo
    onDropRejected: (events) => {
      setErrorMessages([]);
      const messages: { [key: string]: string } = {};

      events.forEach((event) => {
        event.errors.forEach((error) => {
          messages[error.code] = error.message;
        });
      });

      setErrorMessages(Object.keys(messages).map((id) => messages[id]));
    },
    onDrop: (acceptedFiles) => {
      if (uploadedFiles.length + acceptedFiles.length > MAX_FILES) {
        toast({
          title: `最多上传 ${MAX_FILES} 张图片`,
          duration: 3000,
          isClosable: true,
          position: 'top-right',
          status: 'error',
        });
      } else {
        setErrorMessages([]);
        handleFileAccept(acceptedFiles.map((file) => createPreviewMedia(file)));
      }
    },
  });

  useLayoutEffect(() => {
    setErrorMessages([]);
  }, [isDragActive]);

  useEffect(() => {
    errorMessages && setTimeout(() => setErrorMessages([]), 10000);
  }, [errorMessages]);

  useImperativeHandle(ref, () => {
    return {};
  });

  return (
    <Center
      cursor="pointer"
      border="8px dashed"
      borderColor="base.850"
      borderRadius="xl"
      flexDirection="column"
      {...getRootProps({ className: 'dropzone' })}
    >
      <Flex
        w="full"
        h="full"
        borderRadius="md"
        backdropFilter="auto"
        _hover={{
          backdropBlur: '3xl',
          textShadow: textShadow,
        }}
        bg="base.950"
        transition="all 0.2s"
        p={10}
        align="center"
        justify="center"
      >
        <input {...getInputProps()} />
        <VStack textAlign="center" spacing={1} position="relative">
          <Box fontWeight="bold" fontSize="2xl">
            {isDragActive ? (
              <Text color="var(--accent-color)">拖到这里...</Text>
            ) : (
              t('common.uploadText')
            )}
          </Box>
          <Box maxWidth="container.sm">
            <Text mt={4}>为了更好的训练效果，我们建议上传20-30张图片</Text>
          </Box>
          {errorMessages?.length !== 0 && (
            <Box mt={2} color="red.500">
              <Text fontWeight="bold">上传错误:</Text>
              {errorMessages?.map((error) => (
                <Box key={error}>
                  {error
                    .replace('10000000 bytes', '图片过大')
                    .replace('many files', `最多上传${MAX_FILES}张图片`)}
                </Box>
              ))}
            </Box>
          )}
        </VStack>
      </Flex>
    </Center>
  );
});
